package cn.itsource.org.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.digest.MD5;
import cn.itsource.basic.config.exception.BusinessException;
import cn.itsource.basic.service.impl.BaseServiceImpl;
import cn.itsource.basic.util.AjaxResult;
import cn.itsource.basic.util.RedisService;
import cn.itsource.basic.util.message.SendMobileMessageService;
import cn.itsource.org.mapper.UserMapper;
import cn.itsource.org.pojo.domain.User;
import cn.itsource.org.pojo.dto.LoginDto;
import cn.itsource.org.pojo.vo.LoginInfo;
import cn.itsource.org.query.UserQuery;
import cn.itsource.org.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Optional;

@Service
@Slf4j
//Propagation.SUPPORTS:支持别人事务
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class UserServiceImpl extends BaseServiceImpl<User, UserQuery> implements IUserService {
    //基础查询由继承得到

    @Autowired
    private RedisService redisService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private SendMobileMessageService sendMobileMessageService;

    @Override
    public AjaxResult checkPhone(String phone) {
        //1.验证手机号合法性
        boolean mobile = Validator.isMobile(phone);
        if (!mobile){
            throw new BusinessException("手机号有误,请重新输入...");
        }

        //2.校验手机号是否被注册过
        User user = userMapper.findByPhone(phone);

        if (user != null){
            throw new BusinessException("用户已经注册过了...");
        }

        return AjaxResult.createSuccess("手机号验证通过");

    }


    /**
     * 发送验证码
     * @param phone
     * @return
     */
    @Override
    public AjaxResult sendMobileCode(String phone, HttpServletRequest request) {
        //验证手机号
        boolean mobile = Validator.isMobile(phone);
        if (!mobile){
            throw new BusinessException("手机号有误,请重新输入...");
        }

        //2.校验手机号是否被注册过
        User user = userMapper.findByPhone(phone);

        if (user != null){
            throw new BusinessException("用户已经注册过了...");
        }

      /*  //3.拦截同一个ip一直获取验证码
        String ipPhoneStr = request.getRemoteAddr() + request.getRequestURI();

        String res = redisService.getKeyObjectValue(ipPhoneStr, String.class);
        if (res != null){
            throw new BusinessException("兄die,你不正常...");
        }
        //存ip到redis中,保持1分钟,1分钟内重复获取抛出上面的异常
        redisService.setStringKeyAndValue(ipPhoneStr,phone,1);
*/
        //4.生成验证码,保存到redis 5分钟
        String code = RandomUtil.randomNumbers(4);
        //phone:手机号  code:验证码
        redisService.setStringKeyAndValue(phone,code,5);
        log.info("[宠物乐园验证码]:{}",code);

        //调用发送验证码的服务 打印知道存到redis里面的验证码就行了,不发送
        //sendMobileMessageService.sendMobileMessage(phone,code);
        return AjaxResult.createSuccess("发送验证码成功");
    }

    public static void main(String[] args) {
        String code = "6666";
        String a = "6666";
        String b = "6666";
        String c = "6666";
        log.info("[宠物乐园验证码]:"+ code+",a的值，"+a+",b得知"+b);

        log.info("[宠物乐园验证码]:{},{},{},{}",code,a,b,c);
    }

    @Override
    public AjaxResult registerUser(User user) {
        //验证手机号
        boolean mobile = Validator.isMobile(user.getPhone());
        if (!mobile){
            throw new BusinessException("手机号有误,请重新输入...");
        }

        //2.校验手机号是否被注册过
        User dbUser = userMapper.findByPhone(user.getPhone());

        if (dbUser != null){
            throw new BusinessException("用户已经注册过了...");
        }

        //获取Redis的验证码,如果不存在,已失效
        String code = redisService.getKeyObjectValue(user.getPhone(), String.class);
        Optional.ofNullable(code).orElseThrow(() -> new BusinessException("验证码已经失效,请重新获取"));

        //比对验证码
        if (!StringUtils.equals(user.getCode(),code)){
            throw new BusinessException("验证码错误...");
        }

        //通过钩子设置盐和密码
        user.init();

        //注册账号入库
        userMapper.insertSelective(user);

        return AjaxResult.createSuccess();
    }

    @Override
    public AjaxResult loginUser(LoginDto loginDto) {

        //1.通过username匹配三个字段
        User dbUser = userMapper.selectByThreeFiled(loginDto.getUsername());

        //2.如果没有，抛异常
        if (dbUser == null) {
            throw new BusinessException("账号密码不匹配1111");
        }

        //3.如果有，页面密码  + 老盐 加密   === 和 数据库password比对
        String pagePwd = MD5.create().setSalt(dbUser.getSalt().getBytes()).digestHex(loginDto.getPassword());
        if (!StringUtils.equals(pagePwd,dbUser.getPassword())){
            throw new BusinessException("账号密码不匹配2222");
        }

        //4.比对通过，建立token，
        String token = IdUtil.fastSimpleUUID();

        //5.复制字段                                     getId  setUserId
        LoginInfo loginInfo = BeanUtil.copyProperties(dbUser, LoginInfo.class);
        loginInfo.setToken(token);
        loginInfo.setUserId(dbUser.getId());

        //6.存redis
        redisService.setStringKeyAndValue(token,loginInfo,30);

        return AjaxResult.createSuccess(loginInfo);
    }


}
